package com.wolfeyes.common.utils.translation;

import java.lang.reflect.Method;
import java.util.List;

//import com.wolfeyes.common.utils.translation.SysDictDO;
import com.wolfeyes.common.utils.character.ParamUtils;
import com.wolfeyes.common.utils.reflect.proxy.jdkproxy.simple.Person;

/**
 * @core 核心级别  ❤❤❤❤❤
 * @descript SysDict系统(字典 <<==>> 翻译)的转换处理工具类
 * @projectName film
 * @className SysDictUtils.java
 * @author yanyljava
 * @email yanyljava@qq.com
 * @date 2018-09-28 15:53:58
 * @since 2017年02月02日下午5:37:39
 * @createTime 2018年06月09日 下午17:04:13
 * @version 1.0.0
 * @return String
 * @throws Exception
 */
public class SysDictUtils {

	/**
	 * 泛型<T>（字典）getPropertyMethodFormat：get%1$s
	 */
	private static final String getPropertyMethodFormat = "get%1$s";
	
	/**
	 * 泛型<T>（字典）setPropertyMethodFormat：set%1$s
	 */
	private static final String setPropertyMethodFormat = "set%1$s";
	
	/**
	 * 泛型<T>（字典）getPropertyMethod2Format：get%1$s2
	 */
	private static final String getPropertyMethod2Format = "get%1$s2";
	
	/**
	 * 泛型<T>（字典）setPropertyMethod2Format：set%1$s2
	 */
	private static final String setPropertyMethod2Format = "set%1$s2";
	
	/**
	 * 比如：商户名称-快速编码（翻译-->字典）
	 * SysDictUtils.encode(reportUnionpay, "MerchantName", null, merchantNameList);
	 * @title 快速编码（翻译-->字典）property2-->property
	 * @see {@link SysDictUtils #encode()}
	 * @description TODO(随机生成编号)
	 * @param arg 参数说明
	 * @author yanyl
	 * @param po 实体类对象
	 * @param property 属性名
	 * @param priority2 待编码的优先翻译值
	 * @param tList 泛型列表
	 * @since 2018年07月12日上午11:37:39
	 * @return 返回类型 void
	 * @throws Exception
	 */
	public static <Element, Property, T> boolean encode(Element po, Property property, Object priority2, List<T> tList) throws Throwable {
		
		// 获取格式化字符串
		String getPropertyMethodString = String.format(SysDictUtils.getPropertyMethodFormat, property);
		// 获取格式化字符串
		String setPropertyMethodString = String.format(SysDictUtils.setPropertyMethodFormat, property);
		// 获取格式化字符串
		String getPropertyMethod2String = String.format(SysDictUtils.getPropertyMethod2Format, property);
		// 获取格式化字符串
		String setPropertyMethod2String = String.format(SysDictUtils.setPropertyMethod2Format, property);
		
		// 此处涉及Java反射机制--获取泛型类的字节码
		Class<? extends Object> poClazz = po.getClass();
		// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
		Method getPropertyMethod = poClazz.getDeclaredMethod(getPropertyMethodString);//("get"+property);
		// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
		Method setPropertyMethod = poClazz.getDeclaredMethod(setPropertyMethodString, String.class);//("set"+ property + "2", String.class);
		// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
		Method getPropertyMethod2 = poClazz.getDeclaredMethod(getPropertyMethod2String);//("get"+ property + "2");
		// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
		Method setPropertyMethod2 = poClazz.getDeclaredMethod(setPropertyMethod2String, String.class);//("set"+ property + "2", String.class);
		
		// 获取property的返回类型
		Class<? extends Object> propertyReturnType = getPropertyMethod.getReturnType();
		// 泛型（字典）
		Object propertyValue = propertyReturnType.newInstance();
		
		// 回调这个泛型类的对象的method方法
		Object translation = !ParamUtils.isNull(priority2) ? priority2 : getPropertyMethod2.invoke(po);
		// 泛型（翻译）
		Object propertyValue2 = String.valueOf(translation);
		
		// 遍历所有泛型列表（翻译-->字典）
		for (T t : tList) {
			// 此处涉及Java反射机制--获取泛型类的字节码
			Class<? extends Object> tClazz = t.getClass();
			// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
			Method  getNameMethod = tClazz.getDeclaredMethod("getName");
			Method  getValueMethod = tClazz.getDeclaredMethod("getValue");
			// 回调这个泛型类的对象的method方法
			Object object = getNameMethod.invoke(t);
			if(!ParamUtils.isNull(propertyValue2) && !ParamUtils.isNull(object) 
				&& object.equals(propertyValue2)){
				// 泛型（字典）
				propertyValue = getValueMethod.invoke(t);
				break;
			}
		}
		
		// 实例对象（字典）
		setPropertyMethod.invoke(po, propertyValue);
		
		if(!ParamUtils.isNull(priority2)) {
			// 实例对象（翻译）
			setPropertyMethod2.invoke(po, propertyValue2);
		}
		
		return true;
	}
	
	/**
	 * 比如：商户名称-快速解码（字典-->翻译）
	 * SysDictUtils.decode(reportUnionpay, "MerchantName", null, merchantNameList);
	 * @title 快速解码（字典-->翻译）property --> property2
	 * @see {@link Person #Person()}
	 * @description TODO(随机生成编号)
	 * @param arg 参数说明
	 * @author yanyl
	 * @param po 实体类对象
	 * @param property 属性名
	 * @param priority 待解码的优先字典值
	 * @param tList 泛型列表
	 * @since 2018年07月12日上午11:37:39
	 * @return 返回类型 void
	 * @throws Exception
	 */
	public static <Element, Property, T> boolean decode(Element po, Property property, Object priority, List<T> tList) throws Throwable {
		
		// 获取格式化字符串
		String getPropertyMethodString = String.format(SysDictUtils.getPropertyMethodFormat, property);
		// 获取格式化字符串
		String setPropertyMethodString = String.format(SysDictUtils.setPropertyMethodFormat, property);
		// 获取格式化字符串
		String getPropertyMethod2String = String.format(SysDictUtils.getPropertyMethod2Format, property);
		// 获取格式化字符串
		String setPropertyMethod2String = String.format(SysDictUtils.setPropertyMethod2Format, property);
		
		// 此处涉及Java反射机制--获取泛型类的字节码
		Class<? extends Object> poClazz = po.getClass();
		// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
		Method getPropertyMethod = poClazz.getDeclaredMethod(getPropertyMethodString);//("get"+property);
		// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
		Method setPropertyMethod = poClazz.getDeclaredMethod(setPropertyMethodString, String.class);//("set"+ property + "2", String.class);
		// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
		Method getPropertyMethod2 = poClazz.getDeclaredMethod(getPropertyMethod2String);//("get"+ property + "2");
		// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
		Method setPropertyMethod2 = poClazz.getDeclaredMethod(setPropertyMethod2String, String.class);//("set"+ property + "2", String.class);
		
		// 回调这个泛型类的对象的method方法
		Object dictionary = !ParamUtils.isNull(priority) ? priority : getPropertyMethod.invoke(po);
		// 泛型（字典）
		Object propertyValue = String.valueOf(dictionary);
		
		// 获取property2的返回类型
		Class<? extends Object> property2ReturnType = getPropertyMethod2.getReturnType();
		// 泛型（翻译）
		Object propertyValue2 = property2ReturnType.newInstance();
		
		// 遍历所有泛型列表（字典-->翻译）
		for (T t : tList) {
			// 此处涉及Java反射机制--获取泛型类的字节码
			Class<? extends Object> tClazz = t.getClass();
			// getDeclaredMethod获取泛型类的某个固定方法 参数为 方法名 参数列表
			Method  getNameMethod = tClazz.getDeclaredMethod("getName");
			Method  getValueMethod = tClazz.getDeclaredMethod("getValue");
			// 回调这个泛型类的对象的method方法
			Object object = getValueMethod.invoke(t);
			if(!ParamUtils.isNull(propertyValue) && !ParamUtils.isNull(object) 
				&& object.equals(propertyValue)){
				// 泛型（字典）
				propertyValue2 = getNameMethod.invoke(t);
				break;
			}
		}
		
		if(!ParamUtils.isNull(priority)) {
			// 实例对象（字典）
			setPropertyMethod.invoke(po, propertyValue);
		}
		
		// 实例对象（翻译）
		setPropertyMethod2.invoke(po, propertyValue2);
		
		return true;
	}
	
}

